package org.opensuse.bs.ui.actions;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
import org.opensuse.bs.ui.BSUIPlugin;
import org.opensuse.bs.ui.OSC;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class NewAction implements IObjectActionDelegate {
	private Object selected;
	
	private class NewPackageDialog extends Dialog {
		private Text packagename;
		private Text title;
		private Text des;
		
		protected NewPackageDialog(Shell parentShell) {
			super(parentShell);
		}
		
		protected Control createDialogArea(Composite parent) {
			Composite client = new Composite(parent, SWT.NONE);
			GridLayout layout = new GridLayout();
			client.setLayout(layout);
			layout.numColumns = 2;
			
			Label label1 = new Label(client, SWT.NONE);
			label1.setText("Package Name: ");
			packagename = new Text(client, SWT.BORDER);
			GridData gd = new GridData();
			packagename.setLayoutData(gd);
			gd.grabExcessHorizontalSpace = true;
			gd.horizontalAlignment = SWT.FILL;
			
			Label label2 = new Label(client, SWT.NONE);
			label2.setText("Title: ");
			title = new Text(client, SWT.BORDER);
			gd = new GridData();
			title.setLayoutData(gd);
			gd.grabExcessHorizontalSpace = true;
			gd.horizontalAlignment = SWT.FILL;
			
			Label label3 = new Label(client, SWT.NONE);
			label3.setText("Description: ");
			des = new Text(client, SWT.BORDER|SWT.V_SCROLL|SWT.H_SCROLL);
			gd = new GridData();
			des.setLayoutData(gd);
			gd.grabExcessHorizontalSpace = true;
			gd.horizontalAlignment = SWT.FILL;
			gd.widthHint = 200;
			gd.heightHint = 100;
			
			return client;
		}
		
		protected  void 	okPressed() {
			final String pn = packagename.getText().trim();
			String user = BSUIPlugin.getDefault().getUser();
			final IProject project = (IProject) selected;
			final IFolder f = project.getFolder(pn);
			try {
				if(!f.exists()) {
					DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
					DocumentBuilder builder = factory.newDocumentBuilder();
					Document doc = builder.newDocument();
					
					Element pkg = doc.createElement("package");
					pkg.setAttribute("name", pn);
					doc.appendChild(pkg);
					Element titlen = doc.createElement("title");
					titlen.setTextContent(title.getText().trim());
					pkg.appendChild(titlen);
					Element desn = doc.createElement("description");
					desn.setTextContent(des.getText().trim());
					pkg.appendChild(desn);
					Element person = doc.createElement("person");
					person.setAttribute("role", "maintainer");
					person.setAttribute("userid", user);
					pkg.appendChild(person);
					person = doc.createElement("person");
					person.setAttribute("role", "bugowner");
					person.setAttribute("userid", user);
					pkg.appendChild(person);
					
					File file = OSC.toFile(doc, "AddNewPackage");
					Vector<String> result = OSC.run("meta pkg "+project.getName()+" "+pn+" -F "+file.getAbsolutePath());
					file.delete();
					if(result.isEmpty())return;
					WorkspaceJob job = new WorkspaceJob("Creating package "+pn) {
						public IStatus runInWorkspace(IProgressMonitor monitor)
								throws CoreException {
							IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
							File dir = new File(root.getLocation().toOSString());
							String cmd = "co "+project.getName()+" "+f.getName();
							Vector<String> result = OSC.run(cmd, null, dir);
							if(result.isEmpty()) {
								return Status.CANCEL_STATUS;
							}
							project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
							return Status.OK_STATUS;
						}
					};
					job.schedule();
				}
			}catch(Exception e) {
				e.printStackTrace();
			}
			close();
		}
	}
	
	private class NewFileDialog extends Dialog {
		private Text filename;
		
		protected NewFileDialog(Shell parentShell) {
			super(parentShell);
		}
		
		protected Control createDialogArea(Composite parent) {
			Composite client = new Composite(parent, SWT.NONE);
			
			GridLayout layout = new GridLayout();
			client.setLayout(layout);
			layout.numColumns = 2;
			
			Label label1 = new Label(client, SWT.NONE);
			label1.setText("File Name: ");
			filename = new Text(client, SWT.BORDER);
			GridData gd = new GridData();
			filename.setLayoutData(gd);
			gd.grabExcessHorizontalSpace = true;
			gd.widthHint = 200;
			
			return client;
		}
		
		protected  void 	okPressed() {
			final String fn = filename.getText().trim();
			WorkspaceJob job = new WorkspaceJob("Creating file "+fn) {
				public IStatus runInWorkspace(IProgressMonitor monitor)
						throws CoreException {
					IFolder folder = (IFolder) selected;
					IFile f = folder.getFile(fn);
					if(!f.exists()) {
						ByteArrayInputStream in = new ByteArrayInputStream(new byte[0]);
						f.create(in, true, null);
						File dir = new File(folder.getRawLocation().toOSString());
						if(!dir.exists() || !dir.isDirectory()) {
							return Status.CANCEL_STATUS;
						}
						OSC.run("add "+fn, null, dir);
					}
					return Status.OK_STATUS;
				}
			};
			job.schedule();
			close();
		}
	}
	
	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
	}
	
	public void run(IAction action) {
		if(selected instanceof IProject) {
			Dialog dialog = new NewPackageDialog(null);
			dialog.open();
		} else if(selected instanceof IFolder) {
			Dialog dialog = new NewFileDialog(null);
			dialog.open();
		}
	}
	
	public void selectionChanged(IAction action, ISelection selection) {
		if(selection instanceof ITreeSelection) {
			TreePath[] paths = ((ITreeSelection) selection).getPaths();
			if(paths.length != 0) {
				selected = paths[0].getLastSegment();
			}
			else {
				selected = new Object();
			}
		}
	}

}
